package com.ruoyi.pojo.tools;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.jnxx.basic.util.HttpTool;
import com.jnxx.task.domain.OkrStaff;
import com.jnxx.task.mapper.OkrStaffMapper;
import com.jnxx.task.tools.SendToOKR;
import com.jnxx.task.vo.OKRRequestParamsVo;
import com.jnxx.task.vo.TextCardVo;
import com.ruoyi.common.exception.GlobalException;
import com.ruoyi.domain.*;
import com.ruoyi.mapper.*;
import com.ruoyi.service.impl.TChargeSheetServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;


@Slf4j
@Component
public class ApprovalTool {


    @Autowired
    private OkrStaffMapper okrStaffMapper;
    @Autowired
    private TCopyRecordMapper copyRecordMapper;
    @Autowired
    private TDataInfoMapper dataInfoMapper;
    @Autowired
    private TAccountMapper accountMapper;
    @Autowired
    private TAccountRecordMapper accountRecordMapper;
    @Autowired
    private SendToOKR sendToOKRTool;
    @Autowired
    private TChargeSheetServiceImpl chargeSheetService;
    @Autowired
    private TRequestFormMapper requestFormMapper;
    @Autowired
    private TPathApproverMapper pathApproverMapper;
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;


    /*类型标识
        RaiseMoney-加钱   DeductMoney-扣钱  account -账户 id 2
    *  ChannelAccount - 渠道账户  remark - 备注
    *
    * */
    /*定时任务处理抄送单 - 进行抄送 - 扣款或加款*/
    @Scheduled(fixedDelay = 60000)
    public synchronized void pushAndAccount(){
        //查询待处理的抄送单  0
       List<TCopyRecord> copyRecords = copyRecordMapper.loadByStatus(2);
        if(copyRecords.size() == 0){
            return;
        }
        for (TCopyRecord copyRecord : copyRecords) {
           try {
               TRequestForm requestForm = requestFormMapper.selectTRequestFormById(copyRecord.getFromId());
               Integer fromType = requestForm.getFromType();
               if (fromType!=null){
                   if (fromType.equals(2)){//卡密
                       handleCardMessage(copyRecord,requestForm);
                   }else if (fromType.equals(3)){//回款
                       handlePayBackMessage(copyRecord,requestForm);
                   }else {
                       handleMessage(copyRecord,requestForm);
                   }
               }else {
                   handleMessage(copyRecord,requestForm);
               }
           }catch (Exception e){
               log.error("循环执行消息异常："+copyRecords);
           }
        }
    }

    /*重要参数  账单表id 、 还款金额*/
    @Transactional(isolation = Isolation.READ_COMMITTED ,rollbackFor = Exception.class)
    public void handlePayBackMessage(TCopyRecord copyRecord, TRequestForm requestForm) {
        copyRecord.setMakeStatus(0);
        copyRecord.setChangTime(new Date());
        copyRecordMapper.updateTCopyRecord(copyRecord);
        String statementId = null;
        String monney = null;
        String account = null;
        List<TDataInfo> dataInfos = dataInfoMapper.loadByFromId(copyRecord.getFromId());
        String orderNo = generateOrderNumber();
        for (TDataInfo dataInfo : dataInfos) {
            if (dataInfo.getIdentification().equals("statementId")){
                statementId = dataInfo.getDataContent();
            }
            if (dataInfo.getIdentification().equals("RaiseMoney")){
                monney = dataInfo.getDataContent();
            }
            if (dataInfo.getIdentification().equals("account")){
                account = dataInfo.getDataContent();
            }
        }
        BigDecimal monneyDce = new BigDecimal(monney);
        if (account!=null){
            TAccount tAccount = accountMapper.loadByAccName(account);
            BigDecimal balance = tAccount.getBalance();
            TAccountRecord tAccountRecord = new TAccountRecord();
            BigDecimal newBalance = balance.add(monneyDce);
            tAccount.setBalance(newBalance);
            tAccountRecord.setAmountBefore(balance);
            tAccountRecord.setAmountAfter(newBalance);
            tAccountRecord.setType(1);
            tAccount.setChangeTime(new Date());
            tAccountRecord.setAmount(monneyDce);
            tAccountRecord.setAccountId(tAccount.getId());
            tAccountRecord.setCreatTime(new Date());
            tAccountRecord.setFromId(copyRecord.getFromId());
            accountMapper.updateTAccount(tAccount);
            accountRecordMapper.insertTAccountRecord(tAccountRecord);
        }
        HashMap<String, String> map = new HashMap<>();
        String descript = "<div class=\"gray\">%s</div> <div class=\"normal\">您有新的抄送单等待查看</div><div class=\"highlight\">"+requestForm.getName()+"</div>";
        StringBuilder stringBuilder = new StringBuilder();
        //查询要发送的管理员id
        String makeUser = copyRecord.getMakeUser();
        String[] split = makeUser.split(",");
        ArrayList<Integer> integers = new ArrayList<>();
        if (split.length >= 1) {
            List<Integer> result = Arrays.stream(split)
                    .map(Integer::parseInt)
                    .collect(Collectors.toList());
            integers.addAll(result);
        }
        List<OkrStaff> byIds = okrStaffMapper.findByIds(integers);
        byIds.forEach(b->{
            stringBuilder.append(b.getUserId()).append("|");
        });
        if (stringBuilder.length()>0){
            stringBuilder.deleteCharAt(stringBuilder.length() - 1);
        }
        map.put("descript",descript);
        map.put("touser",stringBuilder.toString());
        TextCardVo textCardVo = new TextCardVo();
        OKRRequestParamsVo paramsVo = new OKRRequestParamsVo();
        textCardVo.setUrl("qy.llczy.com/#/pages/examine/approvalPage?fromId="+ copyRecord.getFromId()+"&status=1");
        textCardVo.setBtntxt("查看详情");
        textCardVo.setTitle("抄送单推送通知");
        paramsVo.setEnable_duplicate_check("0");
        paramsVo.setAgentid("1000033");
        paramsVo.setEnable_id_trans("0");
        paramsVo.setMsgtype("textcard");
        String resp = sendToOKRTool.sendMessage(map, paramsVo, textCardVo);
        log.info("抄送单推送状态"+resp);
        OkrStaff dbStaff = okrStaffMapper.loadByFromId(copyRecord.getFromId());
        TChargeSheet chargeSheet = chargeSheetService.selectTChargeSheetByFromId(copyRecord.getFromId());
        if (chargeSheet!=null){
            return;
        }
        //组装参数 - 保存推送单
        TChargeSheet tChargeSheet = new TChargeSheet();
        tChargeSheet.setAgentCode(statementId);//商品id
        tChargeSheet.setAgentOrderNo(orderNo);
        tChargeSheet.setFromId(copyRecord.getFromId());
        tChargeSheet.setOperatorPhone(dbStaff.getPhone()); //申请人电话
        tChargeSheet.setPrice(monneyDce);
        tChargeSheet.setRemark("后付回款"); //备注
        tChargeSheet.setPaymentType("AddFunds");
        tChargeSheet.setOperationType("Agent"); //email
        tChargeSheet.setStatus("1");
        chargeSheetService.insertTChargeSheet(tChargeSheet);
    }

    @Transactional(isolation = Isolation.READ_COMMITTED ,rollbackFor = Exception.class)
    public void handleCardMessage(TCopyRecord copyRecord,TRequestForm requestForm) {
        copyRecord.setMakeStatus(0);
        copyRecord.setChangTime(new Date());
        copyRecordMapper.updateTCopyRecord(copyRecord);
        //加扣款 - 查出data中的固定标识
        String type = null;

        String monney = null;
        String account = null;

        String comment = null;
        String productId = null;
        String count = null;//数量
        String email = null;
        String title = null;//标题

        // 生成指定长度的随机数
        String orderNo = generateOrderNumber();
        List<TDataInfo> dataInfos = dataInfoMapper.loadByFromId(copyRecord.getFromId());
        //RaiseMoney DeductMoney   Credit ArtificialAdd  ArtificialDel
        //代理加款     代理扣款    授信      人工加款    人工扣款
        //出账户 outAccount  入账户  enterAccount 金额 amount
        for (TDataInfo dataInfo : dataInfos) {
            if (dataInfo.getIdentification().equals("RaiseMoney")){//加钱
                type = "RaiseMoney";
                monney = dataInfo.getDataContent();
            }
            if (dataInfo.getIdentification().equals("account")){
                account = dataInfo.getDataContent();
            }
            if (dataInfo.getIdentification().equals("comment")){
                comment = dataInfo.getDataContent();
            }
            //出账户 outAccount  入账户  enterAccount 金额 amount
            if (dataInfo.getIdentification().equals("productId")){
                productId = dataInfo.getDataContent();
            }
            if (dataInfo.getIdentification().equals("count")){
                count = dataInfo.getDataContent();
            }
            if (dataInfo.getIdentification().equals("email")){
                email = dataInfo.getDataContent();
            }
            if (dataInfo.getIdentification().equals("title")){
                title = dataInfo.getDataContent();
            }
        }
        String accountType = "";
        BigDecimal monneyDce = new BigDecimal(monney);
        if (account!=null){
            //根据数据加扣款 - 保存账户扣款记录  
            TAccount tAccount = accountMapper.loadByAccName(account);
            BigDecimal balance = tAccount.getBalance();
            TAccountRecord tAccountRecord = new TAccountRecord();
            accountType = tAccount.getAccountType();
            if ("RaiseMoney".equals(type)) {
                BigDecimal newBalance = balance.add(monneyDce);
                tAccount.setBalance(newBalance);
                tAccountRecord.setAmountBefore(balance);
                tAccountRecord.setAmountAfter(newBalance);
                tAccountRecord.setType(1);
            }
            tAccount.setChangeTime(new Date());
            tAccountRecord.setAmount(monneyDce);
            tAccountRecord.setAccountId(tAccount.getId());
            tAccountRecord.setCreatTime(new Date());
            tAccountRecord.setFromId(copyRecord.getFromId());
            accountMapper.updateTAccount(tAccount);
            accountRecordMapper.insertTAccountRecord(tAccountRecord);
        }
        //操作完数据 发送抄送消息
        HashMap<String, String> map = new HashMap<>();
        String descript = "<div class=\"gray\">%s</div> <div class=\"normal\">您有新的抄送单等待查看</div><div class=\"highlight\">"+requestForm.getName()+"</div>";
        StringBuilder stringBuilder = new StringBuilder();
        //查询要发送的管理员id
        String makeUser = copyRecord.getMakeUser();
        String[] split = makeUser.split(",");
        ArrayList<Integer> integers = new ArrayList<>();
        if (split.length >= 1) {
            List<Integer> result = Arrays.stream(split)
                    .map(Integer::parseInt)
                    .collect(Collectors.toList());
            integers.addAll(result);
        }
        List<OkrStaff> byIds = okrStaffMapper.findByIds(integers);
        byIds.forEach(b->{
            stringBuilder.append(b.getUserId()).append("|");
        });
        if (stringBuilder.length()>0){
            stringBuilder.deleteCharAt(stringBuilder.length() - 1);
        }
        map.put("descript",descript);
        map.put("touser",stringBuilder.toString());
        TextCardVo textCardVo = new TextCardVo();
        OKRRequestParamsVo paramsVo = new OKRRequestParamsVo();
        textCardVo.setUrl("qy.llczy.com/#/pages/examine/approvalPage?fromId="+ copyRecord.getFromId()+"&status=1");
        textCardVo.setBtntxt("查看详情");
        textCardVo.setTitle("抄送单推送通知");
        paramsVo.setEnable_duplicate_check("0");
        paramsVo.setAgentid("1000033");
        paramsVo.setEnable_id_trans("0");
        paramsVo.setMsgtype("textcard");
        String resp = sendToOKRTool.sendMessage(map, paramsVo, textCardVo);
        log.info("抄送单推送状态"+resp);
        //抄送成功 - 发起渠道加款同步

        OkrStaff dbStaff = okrStaffMapper.loadByFromId(copyRecord.getFromId());
        TChargeSheet chargeSheet = chargeSheetService.selectTChargeSheetByFromId(copyRecord.getFromId());
        if (chargeSheet!=null){
            return;
        }
        //组装参数 - 保存推送单
        TChargeSheet tChargeSheet = new TChargeSheet();
        tChargeSheet.setAgentCode(productId);//商品id
        tChargeSheet.setAgentOrderNo(orderNo);
        tChargeSheet.setFromId(copyRecord.getFromId());
        tChargeSheet.setOperatorPhone(dbStaff.getPhone()); //申请人电话
        tChargeSheet.setPrice(monneyDce);
        tChargeSheet.setRemark(comment); //备注
        tChargeSheet.setPaymentType(count);//数量
        tChargeSheet.setOperationType(email); //email
        tChargeSheet.setTitleMsg(title);
        tChargeSheet.setStatus("1");
        tChargeSheet.setAccountType(accountType);
        chargeSheetService.insertTChargeSheet(tChargeSheet);
    }


    @Transactional(isolation = Isolation.READ_COMMITTED ,rollbackFor = Exception.class)
    public void handleMessage(TCopyRecord copyRecord,TRequestForm requestForm) {
        copyRecord.setMakeStatus(0);
        copyRecord.setChangTime(new Date());
        copyRecordMapper.updateTCopyRecord(copyRecord);
        //加扣款 - 查出data中的固定标识
        String type = null;
        String operationType = "Agent";
        String monney = null;
        String account = null;
        String channelAccount = null;

        String outAccount = null;
        String enterAccount = null;
        //String amount = null;

        // 生成指定长度的随机数
        StringBuilder randomPart = new StringBuilder();
        for (int i = 0; i < 8; i++) {
            randomPart.append(new Random().nextInt(10)); // 生成0-9之间的随机数
        }
        String remark = randomPart.toString();

        List<TDataInfo> dataInfos = dataInfoMapper.loadByFromId(copyRecord.getFromId());
        //RaiseMoney DeductMoney   Credit ArtificialAdd  ArtificialDel
        //代理加款     代理扣款    授信      人工加款    人工扣款
        //出账户 outAccount  入账户  enterAccount 金额 amount
        for (TDataInfo dataInfo : dataInfos) {
            if (dataInfo.getIdentification().equals("RaiseMoney")){//加钱
                type = "RaiseMoney";
                monney = dataInfo.getDataContent();
            }
            //操作类型  Agent(代理)  Credit(授信) Artificial（手动)
            if (dataInfo.getIdentification().equals("DeductMoney")){//扣钱
                type = "DeductMoney";
                monney = dataInfo.getDataContent();
            }
            //人工加款
            if(dataInfo.getIdentification().equals("ArtificialAdd")){
                type = "RaiseMoney";
                operationType = "Artificial";
                monney = dataInfo.getDataContent();
            }
            //人工扣款
            if(dataInfo.getIdentification().equals("ArtificialDel")){
                type = "DeductMoney";
                operationType = "Artificial";
                monney = dataInfo.getDataContent();
            }
            /*授信*/
            if (dataInfo.getIdentification().equals("CreditAdd")){
                type = "RaiseMoney";
                operationType = "Credit";
                monney = dataInfo.getDataContent();
            }
            /*清授信*/
            if (dataInfo.getIdentification().equals("CreditDel")){
                type = "DeductMoney";
                operationType = "Credit";
                monney = dataInfo.getDataContent();
            }

            /*新授信*/
            if (dataInfo.getIdentification().equals("NewCreditAdd")){
                type = "RaiseMoney";
                operationType = "NewCredit";
                monney = dataInfo.getDataContent();
            }
            /*新清授信*/
            if (dataInfo.getIdentification().equals("NewCreditDel")){
                type = "DeductMoney";
                operationType = "NewCredit";
                monney = dataInfo.getDataContent();
            }

            if (dataInfo.getIdentification().equals("account")){
                account = dataInfo.getDataContent();
            }
            if (dataInfo.getIdentification().equals("ChannelAccount")){ //下游渠道名称
                channelAccount = dataInfo.getDataContent();
            }
            if (dataInfo.getIdentification().equals("remark")){
                remark = dataInfo.getDataContent();
            }
            //出账户 outAccount  入账户  enterAccount 金额 amount
            if (dataInfo.getIdentification().equals("outAccount")){
                outAccount = dataInfo.getDataContent();
            }
            if (dataInfo.getIdentification().equals("enterAccount")){
                enterAccount = dataInfo.getDataContent();
            }
            if (dataInfo.getIdentification().equals("amount")){
                monney = dataInfo.getDataContent();
            }
        }
        if (account==null && monney==null && type==null){
           //后期跟账户款项无关的审批添加 抄送
            return;
        }
        if (outAccount!=null && enterAccount!=null && monney!=null){
            //为内部转账 执行内部转账
            BigDecimal decimal = new BigDecimal(monney);
            saveAccountLog(copyRecord, outAccount, decimal,enterAccount);
        }
        BigDecimal monneyDce = new BigDecimal(monney);
        String accountType = "";
        if (account!=null){
            //根据数据加扣款 - 保存账户扣款记录
            TAccount tAccount = accountMapper.loadByAccName(account);
            BigDecimal balance = tAccount.getBalance();
            TAccountRecord tAccountRecord = new TAccountRecord();
            accountType = tAccount.getAccountType();
            if (("DeductMoney").equals(type)){
                BigDecimal newBalance = balance.subtract(monneyDce);
                if (newBalance.compareTo(BigDecimal.ZERO)<=0){
                    log.info("账户余额已不足");//后期看是否需要失败或者加预警
                }
                tAccount.setBalance(newBalance);
                tAccountRecord.setAmountBefore(balance);
                tAccountRecord.setAmountAfter(newBalance);
                tAccountRecord.setType(0);
            }
            if ("RaiseMoney".equals(type)) {
                BigDecimal newBalance = balance.add(monneyDce);
                tAccount.setBalance(newBalance);
                tAccountRecord.setAmountBefore(balance);
                tAccountRecord.setAmountAfter(newBalance);
                tAccountRecord.setType(1);
            }
            tAccount.setChangeTime(new Date());
            tAccountRecord.setAmount(monneyDce);
            tAccountRecord.setAccountId(tAccount.getId());
            tAccountRecord.setCreatTime(new Date());
            tAccountRecord.setFromId(copyRecord.getFromId());
            accountMapper.updateTAccount(tAccount);
            accountRecordMapper.insertTAccountRecord(tAccountRecord);
        }
        //操作完数据 发送抄送消息
        HashMap<String, String> map = new HashMap<>();
        String descript = "<div class=\"gray\">%s</div> <div class=\"normal\">您有新的抄送单等待查看</div><div class=\"highlight\">"+requestForm.getName()+"</div>";
        StringBuilder stringBuilder = new StringBuilder();
        //查询要发送的管理员id
        String makeUser = copyRecord.getMakeUser();
        String[] split = makeUser.split(",");
        ArrayList<Integer> integers = new ArrayList<>();
        if (split.length >= 1) {
            List<Integer> result = Arrays.stream(split)
                    .map(Integer::parseInt)
                    .collect(Collectors.toList());
            integers.addAll(result);
        }
        List<OkrStaff> byIds = okrStaffMapper.findByIds(integers);
        byIds.forEach(b->{
            stringBuilder.append(b.getUserId()).append("|");
        });
        if (stringBuilder.length()>0){
            stringBuilder.deleteCharAt(stringBuilder.length() - 1);
        }
        map.put("descript",descript);
        map.put("touser",stringBuilder.toString());
        TextCardVo textCardVo = new TextCardVo();
        OKRRequestParamsVo paramsVo = new OKRRequestParamsVo();
        textCardVo.setUrl("qy.llczy.com/#/pages/examine/approvalPage?fromId="+ copyRecord.getFromId()+"&status=1");
        textCardVo.setBtntxt("查看详情");
        textCardVo.setTitle("抄送单推送通知");
        paramsVo.setEnable_duplicate_check("0");
        paramsVo.setAgentid("1000033");
        paramsVo.setEnable_id_trans("0");
        paramsVo.setMsgtype("textcard");
        String resp = sendToOKRTool.sendMessage(map, paramsVo, textCardVo);
        log.info("抄送单推送状态"+resp);
        //抄送成功 - 发起渠道加款同步
        if (channelAccount==null){
            return;
        }
        OkrStaff dbStaff = okrStaffMapper.loadByFromId(copyRecord.getFromId());
        TChargeSheet chargeSheet = chargeSheetService.selectTChargeSheetByFromId(copyRecord.getFromId());
        if (chargeSheet!=null){
            return;
        }
        //组装参数 - 保存推送单
        TChargeSheet tChargeSheet = new TChargeSheet();
        tChargeSheet.setAgentCode(channelAccount);
        tChargeSheet.setAgentOrderNo(remark);
        tChargeSheet.setFromId(copyRecord.getFromId());
        tChargeSheet.setOperatorPhone(dbStaff.getPhone());
        tChargeSheet.setPrice(monneyDce);
        tChargeSheet.setRemark(remark);
        //款项类型  RaiseMoney（加款）  DeductMoney（扣款）
        tChargeSheet.setPaymentType(type);
        //操作类型  Agent(代理)  Credit(授信) Artificial（手动)
        tChargeSheet.setOperationType(operationType);
        tChargeSheet.setAccountType(accountType);
        tChargeSheet.setStatus("1");
        chargeSheetService.insertTChargeSheet(tChargeSheet);
    }

    private void saveAccountLog(TCopyRecord copyRecord, String outAccount, BigDecimal decimal,String enterAccount) {
        TAccount tAccountO = accountMapper.loadByAccName(outAccount);
        BigDecimal balance = tAccountO.getBalance();
        TAccountRecord outAccountRecord = new TAccountRecord();
        BigDecimal newBalance = balance.subtract(decimal);
        tAccountO.setBalance(newBalance);
        outAccountRecord.setAmountBefore(balance);
        outAccountRecord.setAmountAfter(newBalance);
        outAccountRecord.setType(0);
        tAccountO.setChangeTime(new Date());
        outAccountRecord.setAmount(decimal);
        outAccountRecord.setAccountId(tAccountO.getId());
        outAccountRecord.setCreatTime(new Date());
        outAccountRecord.setFromId(copyRecord.getFromId());
        accountMapper.updateTAccount(tAccountO);
        accountRecordMapper.insertTAccountRecord(outAccountRecord);

        //保存入账户的记录 - 加款
        TAccount tAccountT = accountMapper.loadByAccName(enterAccount);
        BigDecimal balanceT = tAccountT.getBalance();
        TAccountRecord enAccountRecord = new TAccountRecord();
        BigDecimal newBalanceT = balanceT.add(decimal);
        tAccountT.setBalance(newBalanceT);
        enAccountRecord.setAmountBefore(balanceT);
        enAccountRecord.setAmountAfter(newBalanceT);
        enAccountRecord.setType(1);
        tAccountT.setChangeTime(new Date());
        enAccountRecord.setAmount(decimal);
        enAccountRecord.setAccountId(tAccountT.getId());
        enAccountRecord.setCreatTime(new Date());
        enAccountRecord.setFromId(copyRecord.getFromId());
        accountMapper.updateTAccount(tAccountT);
        accountRecordMapper.insertTAccountRecord(enAccountRecord);
    }

    @Scheduled(fixedDelay = 60000)
    public synchronized void pushXCAgentAccount(){
       List<TChargeSheet> chargeSheets = chargeSheetService.selectByErrorStatus();

       if(chargeSheets.size() == 0){
            return;
        }
        for (TChargeSheet chargeSheet : chargeSheets) {
            TRequestForm requestForm = requestFormMapper.selectTRequestFormById(chargeSheet.getFromId());
            Integer fromType = requestForm.getFromType();

            if(fromType!=null){
                if (fromType.equals(2)){
                    pushCardMsg(chargeSheet);
                }if (fromType.equals(3)){
                    pushPayBackMsg(chargeSheet);
                }else {
                    pushMsg(chargeSheet);
                }
            }else {
                pushMsg(chargeSheet);
            }
        }
    }

    @Transactional(isolation = Isolation.READ_COMMITTED ,rollbackFor = Exception.class)
    public void pushPayBackMsg(TChargeSheet chargeSheet) {
        HashMap<String, Object> personMap = new HashMap<>();
        personMap.put("statementId", chargeSheet.getAgentCode());
        personMap.put("price", chargeSheet.getPrice());

        String s = HttpTool.sendPost2("http://127.0.0.1:8068/api/xc/agentStatement/pay_back", personMap);
        JSONObject parseObject = JSONObject.parseObject(s);
        String code = parseObject.getString("code");
        String errorMsg = parseObject.getString("errorMsg");
        if ("200".equals(code)) {//处理成功
            String data = parseObject.getString("data");
            log.info("同步回款成功"+errorMsg+":chargeSheetId"+ chargeSheet.getId());
            chargeSheet.setStatus("0");
            OkrStaff okrStaff = okrStaffMapper.loadByFromId(chargeSheet.getFromId());
            chargeSheetService.updateTChargeSheet(chargeSheet);
            sendSuccessMessage("后付回款", chargeSheet.getFromId(),okrStaff.getUserId());
        }
        if ("300".equals(code)){//处理失败
            log.info("同步回款失败-无需同步，账单已完结或异常"+errorMsg+":chargeSheetId"+ chargeSheet.getId());
            chargeSheet.setStatus("0");
            OkrStaff okrStaff = okrStaffMapper.loadByFromId(chargeSheet.getFromId());
            chargeSheetService.updateTChargeSheet(chargeSheet);
            sendSuccessMessage("后付回款", chargeSheet.getFromId(),okrStaff.getUserId());
        }
        throw new RuntimeException("同步失败");
    }

    @Transactional(isolation = Isolation.READ_COMMITTED ,rollbackFor = Exception.class)
    public void pushCardMsg(TChargeSheet chargeSheet) {
        HashMap<String, Object> personMap = new HashMap<>();
        personMap.put("productId", chargeSheet.getAgentCode());
        personMap.put("orderNo", chargeSheet.getAgentOrderNo());
        personMap.put("phone", chargeSheet.getOperatorPhone());
        personMap.put("notes", chargeSheet.getRemark());
        personMap.put("email", chargeSheet.getOperationType());
        personMap.put("count", chargeSheet.getPaymentType());
        personMap.put("title", chargeSheet.getTitleMsg());

        String s = HttpTool.sendPost2("http://127.0.0.1:8068/api/xc/sendCards", personMap);
        JSONObject parseObject = JSONObject.parseObject(s);
        String code = parseObject.getString("code");
        String errorMsg = parseObject.getString("errorMsg");
        if ("200".equals(code)) {
            String data = parseObject.getString("data");
            log.info("同步虚充卡密发送成功"+errorMsg+":chargeSheetId"+ chargeSheet.getId());
            chargeSheet.setStatus("0");
            OkrStaff okrStaff = okrStaffMapper.loadByFromId(chargeSheet.getFromId());
            chargeSheetService.updateTChargeSheet(chargeSheet);
            sendSuccessCardMessage(chargeSheet.getFromId(), okrStaff.getUserId(),data);
        }
        if ("300".equals(code)){//库存不足 - 发送异常消息
            log.info("同步虚充卡密发送成功，但库存不足"+errorMsg+":chargeSheetId"+ chargeSheet.getId());
            chargeSheet.setStatus("0");
            OkrStaff okrStaff = okrStaffMapper.loadByFromId(chargeSheet.getFromId());
            chargeSheetService.updateTChargeSheet(chargeSheet);
            sendErrorCardMessage(chargeSheet.getFromId(), okrStaff.getUserId());
        }
        throw new RuntimeException("同步失败");
    }

    private void sendErrorCardMessage(Long fromId, String userId) {
        try {
            HashMap<String, String> successMap = new HashMap<>();
            String descriptT = "<div class=\"gray\">%s</div> <div class=\"normal\">您的下游卡密出货失败，失败原因：库存不足，请及时补充库存后重新提交审批</div><div class=\"highlight\"></div>";
            successMap.put("descript",descriptT);
            successMap.put("touser", userId);
            TextCardVo textCardVoT = new TextCardVo();
            OKRRequestParamsVo paramsVoT = new OKRRequestParamsVo();
            textCardVoT.setUrl("qy.llczy.com/#/pages/examine/approvalPage?fromId="+fromId+"&status=1");
            textCardVoT.setBtntxt("查看详情");
            textCardVoT.setTitle("下游卡密出货处理结果通知");
            paramsVoT.setEnable_duplicate_check("0");
            paramsVoT.setAgentid("1000033");
            paramsVoT.setEnable_id_trans("0");
            paramsVoT.setMsgtype("textcard");
            String res = sendToOKRTool.sendMessage(successMap, paramsVoT, textCardVoT);
            log.info("审批单处理结果通知状态"+res);
        }catch (Exception e) {
            log.error("审批处理结果通知方法异常"+e);
        }

    }




    private void sendSuccessCardMessage(Long fromId, String userId,String key) {
        try {
            HashMap<String, String> successMap = new HashMap<>();
            String descriptT = "<div class=\"gray\">%s</div> <div class=\"normal\">您的下游卡密出货申请已发送邮件,邮件密码为："+key+"</div><div class=\"highlight\"></div>";
            successMap.put("descript",descriptT);
            successMap.put("touser", userId);
            TextCardVo textCardVoT = new TextCardVo();
            OKRRequestParamsVo paramsVoT = new OKRRequestParamsVo();
            textCardVoT.setUrl("qy.llczy.com/#/pages/examine/approvalPage?fromId="+fromId+"&status=1");
            textCardVoT.setBtntxt("查看详情");
            textCardVoT.setTitle("下游卡密出货处理结果通知");
            paramsVoT.setEnable_duplicate_check("0");
            paramsVoT.setAgentid("1000033");
            paramsVoT.setEnable_id_trans("0");
            paramsVoT.setMsgtype("textcard");
            String res = sendToOKRTool.sendMessage(successMap, paramsVoT, textCardVoT);
            log.info("审批单处理结果通知状态"+res);
        }catch (Exception e) {
            log.error("审批处理结果通知方法异常"+e);
        }

    }


    @Transactional(isolation = Isolation.READ_COMMITTED ,rollbackFor = Exception.class)
    public void pushMsg(TChargeSheet chargeSheet) {
        HashMap<String, Object> personMap = new HashMap<>();
        personMap.put("agentCode", chargeSheet.getAgentCode());
        personMap.put("agentOrderNo", chargeSheet.getAgentOrderNo());
        personMap.put("operatorPhone", chargeSheet.getOperatorPhone());
        personMap.put("price", chargeSheet.getPrice());
        personMap.put("remark", chargeSheet.getRemark());
        personMap.put("operationType", chargeSheet.getOperationType());
        personMap.put("paymentType", chargeSheet.getPaymentType());
        personMap.put("accountType", chargeSheet.getAccountType());//账户类型

        String s = HttpTool.sendPost2("http://127.0.0.1:8068/api/xc/surcharge", personMap);
        JSONObject parseObject = JSONObject.parseObject(s);
        String code = parseObject.getString("code");
        String errorMsg = parseObject.getString("errorMsg");
        if ("200".equals(code)) {
            log.info("同步虚充成功"+errorMsg+":chargeSheetId"+ chargeSheet.getId());
            chargeSheet.setStatus("0");
            OkrStaff okrStaff = okrStaffMapper.loadByFromId(chargeSheet.getFromId());
            chargeSheetService.updateTChargeSheet(chargeSheet);
            sendSuccessMessage("",chargeSheet.getFromId(), okrStaff.getUserId());
        }else {
            throw new RuntimeException("同步失败");
        }
    }

    /*用户手动推送审批提醒*/
    public boolean approvalReminder(String fromId) {
        //查询审批单详情进行推送
        /** 申请单状态  0-待审核  3-审核未通过 1-审核通过 2-审核中 */
        Long aLong = Long.valueOf(fromId);
        TRequestForm requestForm = requestFormMapper.selectTRequestFormById(aLong);
        if (requestForm==null){
            throw new GlobalException("该审批单不存在！");
        }
        if (requestForm.getStatus().equals(4)){
            throw new GlobalException("已撤回的审批单不可推送！");
        }
        if (requestForm.getStatus().equals(3)||requestForm.getStatus().equals(1)){
            throw new GlobalException("该审批单已处理完毕，不需要再推送！");
        }
        Object value = redisTemplate.opsForValue().get("fromId" + requestForm.getId());
        if (value!=null){
            throw new GlobalException("该审批单30分钟内已提醒过！");
        }
       List<TPathApprover> tPathApprovers = pathApproverMapper.loadByFromId(aLong);

        Optional<Integer> highestUnhandledPriority = tPathApprovers.stream()
                .filter(approver -> approver.getStatus() == 0) // 过滤出未处理的记录
                .map(TPathApprover::getPriority)
                .min(Comparator.naturalOrder()); // 假设优先级越小，优先级越高

        List<Long> unhandledApproverIds = new ArrayList<>();

        if (highestUnhandledPriority.isPresent()) {
            // 收集具有最高未处理优先级的approver_id
            unhandledApproverIds.addAll(tPathApprovers.stream()
                    .filter(approver -> approver.getStatus() == 0 // 过滤出未处理的记录  otherRefund
                            && approver.getPriority().equals(highestUnhandledPriority.get())) // 并且优先级匹配
                    .map(TPathApprover::getApproverId) // 映射到approver_id
                    .collect(Collectors.toList())); // 收集到列表中
        }

        StringBuilder stringBuilder = new StringBuilder();
        for (Long id : unhandledApproverIds) {
            OkrStaff staff = okrStaffMapper.findOne(id);
            stringBuilder.append(staff.getUserId()).append("|");
        }
        if (stringBuilder.length()>0){
            stringBuilder.deleteCharAt(stringBuilder.length() - 1);
        }
        OkrStaff dbStaff = okrStaffMapper.findOne(requestForm.getPetitionerId());
        String name = dbStaff.getName();

        HashMap<String, String> map = new HashMap<>();
        String descript = "<div class=\"gray\">%s</div> <div class=\"normal\">您有"+name+"的"+requestForm.getName()+"还未处理"+"</div><div class=\"highlight\"></div>";
        map.put("descript",descript);
        map.put("touser",String.valueOf(stringBuilder));//
        TextCardVo textCardVo = new TextCardVo();
        OKRRequestParamsVo paramsVo = new OKRRequestParamsVo();
        textCardVo.setUrl("qy.llczy.com/#/pages/examine/approvalPage?fromId="+requestForm.getId());
        textCardVo.setBtntxt("查看详情");
        textCardVo.setTitle("审批单推送通知");
        paramsVo.setEnable_duplicate_check("0");
        paramsVo.setAgentid("1000033");
        paramsVo.setEnable_id_trans("0");
        paramsVo.setMsgtype("textcard");
        String resp = sendToOKRTool.sendMessage(map, paramsVo, textCardVo);
        log.info("审批单提醒推送状态"+resp);
        JSONObject jsonObject = JSONObject.parseObject(resp);
        String errcode = jsonObject.getString("errcode");
        if ("0".equals(errcode)){
            //成功  key：value  key:时间
            String key = "fromId"+requestForm.getId();
            redisTemplate.opsForValue().set(key,String.valueOf(stringBuilder),30,TimeUnit.MINUTES);
            return true;
        }else {
            throw new GlobalException("推送失败，请重试！");
        }
    }


    private void sendSuccessMessage(String msg,Long fromId, String userId) {
        try {
            HashMap<String, String> successMap = new HashMap<>();
            String descriptT = "<div class=\"gray\">%s</div> <div class=\"normal\">您的"+msg+"申请已处理完成</div><div class=\"highlight\"></div>";
            successMap.put("descript",descriptT);
            successMap.put("touser", userId);
            TextCardVo textCardVoT = new TextCardVo();
            OKRRequestParamsVo paramsVoT = new OKRRequestParamsVo();
            textCardVoT.setUrl("qy.llczy.com/#/pages/examine/approvalPage?fromId="+fromId+"&status=1");
            textCardVoT.setBtntxt("查看详情");
            textCardVoT.setTitle("审批单处理结果通知");
            paramsVoT.setEnable_duplicate_check("0");
            paramsVoT.setAgentid("1000033");
            paramsVoT.setEnable_id_trans("0");
            paramsVoT.setMsgtype("textcard");
            String res = sendToOKRTool.sendMessage(successMap, paramsVoT, textCardVoT);
            log.info("审批单处理结果通知状态"+res);
        }catch (Exception e) {
            log.error("审批处理结果通知方法异常"+e);
        }

    }

    private static final String PREFIX = "CA";
    private static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
    private static final Random random = new Random();

    public static String generateOrderNumber() {
        String timestamp = dateFormat.format(new Date());
        int randomNum = random.nextInt(900) + 100; // 确保是三位数
        String randomStr = String.format("%03d", randomNum);
        return PREFIX + timestamp + randomStr;
    }


}
